#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
简化版技术分析模块 - 不依赖talib
实现基本的技术指标计算和交易信号生成
"""

import pandas as pd
import numpy as np
import warnings
warnings.filterwarnings('ignore')

class SimpleTechnicalAnalysis:
    """简化版技术分析器"""
    
    def __init__(self):
        pass
    
    def calculate_ma(self, data, period):
        """计算移动平均线"""
        return data.rolling(window=period).mean()
    
    def calculate_ema(self, data, period):
        """计算指数移动平均线"""
        return data.ewm(span=period).mean()
    
    def calculate_rsi(self, data, period=14):
        """计算RSI指标"""
        delta = data.diff()
        gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
        loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
        rs = gain / loss
        rsi = 100 - (100 / (1 + rs))
        return rsi
    
    def calculate_macd(self, data, fast=12, slow=26, signal=9):
        """计算MACD指标"""
        ema_fast = self.calculate_ema(data, fast)
        ema_slow = self.calculate_ema(data, slow)
        macd_line = ema_fast - ema_slow
        signal_line = self.calculate_ema(macd_line, signal)
        histogram = macd_line - signal_line
        
        return {
            'macd': macd_line,
            'signal': signal_line,
            'histogram': histogram
        }
    
    def calculate_bollinger_bands(self, data, period=20, std_dev=2):
        """计算布林带"""
        ma = self.calculate_ma(data, period)
        std = data.rolling(window=period).std()
        
        upper_band = ma + (std * std_dev)
        lower_band = ma - (std * std_dev)
        
        return {
            'upper': upper_band,
            'middle': ma,
            'lower': lower_band
        }
    
    def calculate_indicators(self, data):
        """计算所有技术指标"""
        if data.empty or len(data) < 30:
            return {}
        
        close = data['close']
        high = data['high']
        low = data['low']
        volume = data['volume']
        
        indicators = {}
        
        try:
            # 移动平均线
            indicators['ma5'] = self.calculate_ma(close, 5)
            indicators['ma10'] = self.calculate_ma(close, 10)
            indicators['ma20'] = self.calculate_ma(close, 20)
            indicators['ma60'] = self.calculate_ma(close, 60)
            
            # 指数移动平均线
            indicators['ema5'] = self.calculate_ema(close, 5)
            indicators['ema20'] = self.calculate_ema(close, 20)
            
            # RSI
            indicators['rsi'] = self.calculate_rsi(close)
            
            # MACD
            macd_data = self.calculate_macd(close)
            indicators.update(macd_data)
            
            # 布林带
            bb_data = self.calculate_bollinger_bands(close)
            indicators['bb_upper'] = bb_data['upper']
            indicators['bb_middle'] = bb_data['middle']
            indicators['bb_lower'] = bb_data['lower']
            
            # 成交量移动平均
            indicators['volume_ma'] = self.calculate_ma(volume, 20)
            
            # 通达信买卖线（简化版）
            indicators['buy_line'] = self.calculate_ema(close, 2)
            
            # 简化版卖线计算
            close_slope = close.diff(periods=21)
            sell_base = close_slope * 20 + close
            indicators['sell_line'] = self.calculate_ema(sell_base, 42)
            
        except Exception as e:
            print(f"计算技术指标失败: {e}")
            
        return indicators
    
    def get_trading_signal(self, data):
        """获取交易信号"""
        if data.empty or len(data) < 30:
            return "数据不足"
        
        try:
            indicators = self.calculate_indicators(data)
            current_price = data['close'].iloc[-1]
            
            # 获取最新的指标值
            ma5 = indicators['ma5'].iloc[-1] if 'ma5' in indicators else current_price
            ma20 = indicators['ma20'].iloc[-1] if 'ma20' in indicators else current_price
            ma60 = indicators['ma60'].iloc[-1] if 'ma60' in indicators else current_price
            rsi = indicators['rsi'].iloc[-1] if 'rsi' in indicators else 50
            
            # MACD信号
            macd_line = indicators['macd'].iloc[-1] if 'macd' in indicators else 0
            signal_line = indicators['signal'].iloc[-1] if 'signal' in indicators else 0
            
            # 布林带位置
            bb_upper = indicators['bb_upper'].iloc[-1] if 'bb_upper' in indicators else current_price * 1.02
            bb_lower = indicators['bb_lower'].iloc[-1] if 'bb_lower' in indicators else current_price * 0.98
            
            # 计算信号强度
            signal_score = 0
            
            # 均线信号
            if current_price > ma5 > ma20 > ma60:
                signal_score += 30  # 多头排列
            elif current_price > ma5 > ma20:
                signal_score += 20
            elif current_price > ma5:
                signal_score += 10
            elif current_price < ma5:
                signal_score -= 10
            
            # RSI信号
            if rsi < 30:
                signal_score += 20  # 超卖
            elif rsi < 50:
                signal_score += 10
            elif rsi > 70:
                signal_score -= 20  # 超买
            elif rsi > 50:
                signal_score -= 10
            
            # MACD信号
            if macd_line > signal_line:
                signal_score += 15
            else:
                signal_score -= 15
            
            # 布林带信号
            if current_price < bb_lower:
                signal_score += 15  # 触及下轨，可能反弹
            elif current_price > bb_upper:
                signal_score -= 15  # 触及上轨，可能回调
            
            # 价格动量
            price_change_5d = (current_price - data['close'].iloc[-6]) / data['close'].iloc[-6] * 100
            if price_change_5d > 5:
                signal_score += 10
            elif price_change_5d < -5:
                signal_score -= 10
            
            # 根据得分给出信号
            if signal_score >= 40:
                return "强烈买入"
            elif signal_score >= 20:
                return "买入"
            elif signal_score >= 0:
                return "持有"
            elif signal_score >= -20:
                return "观望"
            elif signal_score >= -40:
                return "卖出"
            else:
                return "强烈卖出"
                
        except Exception as e:
            print(f"计算交易信号失败: {e}")
            return "震荡"
    
    def calculate_volatility(self, data, period=20):
        """计算波动率"""
        if len(data) < period:
            return 0
            
        returns = data['close'].pct_change().dropna()
        volatility = returns.rolling(window=period).std() * np.sqrt(252) * 100
        return volatility.iloc[-1] if not volatility.empty else 0
    
    def calculate_support_resistance(self, data, period=20):
        """计算支撑阻力位"""
        if len(data) < period:
            return None, None
            
        recent_data = data.tail(period)
        resistance = recent_data['high'].max()
        support = recent_data['low'].min()
        
        return support, resistance

# 为了兼容性，创建别名
TechnicalAnalysis = SimpleTechnicalAnalysis
